#include <boost/python/module.hpp>
#include <boost/python/def.hpp>

#include <string>

#include <wx/wx.h>
#include <wx/numdlg.h>
#ifdef __WXMSW__
    #include <wx/msw/registry.h>
#endif // __WXMSW__

namespace py = boost::python;

namespace { // Avoid cluttering the global namespace.


wxString std2wx(const std::string& str)
{
    return wxString(str.c_str(), wxConvLocal);
}

std::string wx2std(const wxString& str)
{
    return str.mb_str(wxConvLocal).data();
}

void alert(std::string sMsg, std::string sTitle = "Alert")
{
    ::wxMessageBox(std2wx(sMsg), std2wx(sTitle), wxICON_EXCLAMATION);
}

void alert_1(std::string sMsg)
{
    alert(sMsg);
}

bool confirm(std::string sMsg, std::string sTitle = "Confirm")
{
    return ::wxMessageBox(std2wx(sMsg), std2wx(sTitle), wxYES_NO) == wxYES;
}

bool confirm_1(std::string sMsg)
{
    return confirm(sMsg);
}

std::string ask_str(std::string sMsg, std::string sTitle = "Input text", std::string sDefault = "")
{
    return wx2std(::wxGetTextFromUser(std2wx(sMsg), std2wx(sTitle), std2wx(sDefault)));
}

std::string ask_str_1(std::string sMsg)
{
    return ask_str(sMsg);
}

std::string ask_str_2(std::string sMsg, std::string sTitle)
{
    return ask_str(sMsg, sTitle);
}

long ask_int(std::string sMsg, std::string sPrompt, std::string sTitle, long value = 0, long min = 0, long max = 100)
{
    return ::wxGetNumberFromUser(std2wx(sMsg), std2wx(sPrompt), std2wx(sTitle), value, min, max);
}

long ask_int_3(std::string sMsg, std::string sPrompt, std::string sTitle)
{
    return ask_int(sMsg, sPrompt, sTitle);
}

long ask_int_4(std::string sMsg, std::string sPrompt, std::string sTitle, long value)
{
    return ask_int(sMsg, sPrompt, sTitle, value);
}

std::string ask_dir(std::string sMsg, std::string sDefault = "")
{
    return wx2std(::wxDirSelector(std2wx(sMsg), std2wx(sDefault)));
}

std::string ask_dir_1(std::string sMsg)
{
    return ask_dir(sMsg);
}

bool shell(std::string sCommand)
{
    return ::wxShell(std2wx(sCommand));
}

#ifdef __WXMSW__

template<class T>
bool reg(const std::string& sKey, const std::string& sName, T value)
{
    wxRegKey regKey(std2wx(sKey));
    return regKey.SetValue(std2wx(sName), value);;
}

bool reg_int(std::string sKey, std::string sName, long value)
{
    return reg(sKey, sName, value);
}

bool reg_str(std::string sKey, std::string sName, std::string value)
{
    return reg(sKey, sName, std2wx(value));
}

#endif // __WXMSW__

void logmsg(std::string sMsg)
{
    ::wxLogMessage(std2wx(sMsg));
}

}; // namespace

BOOST_PYTHON_MODULE(gui)
{
    py::def("alert",   alert_1);
    py::def("alert",   alert);

    py::def("confirm", confirm_1);
    py::def("confirm", confirm);

    py::def("ask_str", ask_str_1);
    py::def("ask_str", ask_str_2);
    py::def("ask_str", ask_str);

    py::def("ask_dir", ask_dir_1);
    py::def("ask_dir", ask_dir);

    py::def("ask_int", ask_int_3);
    py::def("ask_int", ask_int_4);
    py::def("ask_int", ask_int);

    py::def("shell",   shell);

#ifdef __WXMSW__
    py::def("reg_int", reg_int);
    py::def("reg_str", reg_str);
#endif // __WXMSW__

    py::def("log",     logmsg);
}
